#!/usr/bin/env node

/**
 * 代币交易测试脚本
 * 使用指定的代币和地址进行多次交易测试
 */

const axios = require('axios');
const {
  Connection,
  PublicKey,
  LAMPORTS_PER_SOL,
} = require('@solana/web3.js');
const {
  getAssociatedTokenAddress,
  getAccount,
} = require('@solana/spl-token');

// 配置
const API_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:7172';
const DEVNET_RPC = 'https://api.devnet.solana.com';

// 代币信息
const TOKEN_MINT = '6bMwTwA65tumXUquh4ZGxYxmPyy57szPqcPHdjd2qTj1'; // 您创建的代币
const YOUR_ADDRESS = 'shTdKtBScJMC4GkKmasiE9iMKrtZnMFUtwVTdSXsKac'; // 您的地址

// 交易测试数据
const testTrades = [
  {
    type: 'BUY',
    tokenAmount: 1000,
    solAmount: 0.1,
    description: '首次小额购买 - 1000 代币',
  },
  {
    type: 'BUY',
    tokenAmount: 2500,
    solAmount: 0.25,
    description: '中等购买 - 2500 代币',
  },
  {
    type: 'BUY',
    tokenAmount: 5000,
    solAmount: 0.5,
    description: '大额购买 - 5000 代币',
  },
  {
    type: 'BUY',
    tokenAmount: 10000,
    solAmount: 1.0,
    description: 'FOMO购买 - 10000 代币',
  },
  {
    type: 'BUY',
    tokenAmount: 1500,
    solAmount: 0.15,
    description: '逢低吸纳 - 1500 代币',
  },
];

// 模拟交易执行
async function simulateTradeExecution(trade, tradeIndex) {
  console.log(`\n🎯 模拟交易 ${tradeIndex + 1}/${testTrades.length}`);
  console.log(`📝 ${trade.description}`);
  console.log(`💰 类型: ${trade.type}`);
  console.log(`🪙 代币数量: ${trade.tokenAmount}`);
  console.log(`💵 SOL 金额: ${trade.solAmount}`);
  
  // 模拟网络延迟和处理时间
  const processingTime = Math.random() * 2000 + 1000; // 1-3秒
  console.log(`⏳ 处理中... (${(processingTime / 1000).toFixed(1)}s)`);
  
  await new Promise(resolve => setTimeout(resolve, processingTime));
  
  // 模拟成功率 (95%)
  const success = Math.random() > 0.05;
  
  if (success) {
    const mockSignature = `${Math.random().toString(36).substring(2)}${Math.random().toString(36).substring(2)}${Math.random().toString(36).substring(2)}`;
    console.log(`✅ 交易成功!`);
    console.log(`🔗 交易签名: ${mockSignature}`);
    console.log(`🔍 Solscan: https://solscan.io/tx/${mockSignature}?cluster=devnet`);
    
    return {
      success: true,
      signature: mockSignature,
      trade: trade,
    };
  } else {
    console.log(`❌ 交易失败: 网络拥堵或余额不足`);
    return {
      success: false,
      error: '网络拥堵或余额不足',
      trade: trade,
    };
  }
}

// 检查代币信息
async function checkTokenInfo() {
  console.log('🔍 检查代币信息...');
  
  try {
    const response = await axios.get(`${API_URL}/api/tokens?mint=${TOKEN_MINT}`);
    
    if (response.data.success && response.data.tokens.length > 0) {
      const token = response.data.tokens[0];
      console.log('✅ 代币信息获取成功:');
      console.log(`- 名称: ${token.name}`);
      console.log(`- 符号: ${token.symbol}`);
      console.log(`- 小数位: ${token.decimals}`);
      console.log(`- 总供应量: ${token.supply}`);
      console.log(`- 创建者: ${token.creator}`);
      return token;
    } else {
      console.log('⚠️ 未找到代币信息，使用默认配置');
      return {
        name: 'Test Token',
        symbol: 'TEST',
        decimals: 9,
        mint: TOKEN_MINT,
      };
    }
  } catch (error) {
    console.log('⚠️ API调用失败，使用默认配置');
    console.log(`错误: ${error.message}`);
    return {
      name: 'Test Token',
      symbol: 'TEST',
      decimals: 9,
      mint: TOKEN_MINT,
    };
  }
}

// 检查账户余额 (模拟)
async function checkAccountBalance() {
  console.log('\n💰 检查账户状态...');
  
  try {
    // 这里可以实际连接到Solana RPC检查余额
    const connection = new Connection(DEVNET_RPC, 'confirmed');
    const publicKey = new PublicKey(YOUR_ADDRESS);
    
    const balance = await connection.getBalance(publicKey);
    const solBalance = balance / LAMPORTS_PER_SOL;
    
    console.log(`✅ SOL 余额: ${solBalance.toFixed(6)} SOL`);
    
    if (solBalance < 2.0) {
      console.log('⚠️ SOL余额较低，建议先充值');
    }
    
    // 检查代币余额
    try {
      const tokenMint = new PublicKey(TOKEN_MINT);
      const tokenAccount = await getAssociatedTokenAddress(tokenMint, publicKey);
      const account = await getAccount(connection, tokenAccount);
      
      console.log(`✅ 代币余额: ${account.amount.toString()} (原始单位)`);
    } catch {
      console.log(`ℹ️ 尚未持有此代币或代币账户不存在`);
    }
    
    return { solBalance, hasTokens: false };
  } catch (error) {
    console.log(`⚠️ 余额检查失败: ${error.message}`);
    console.log('继续进行模拟交易...');
    return { solBalance: 10.0, hasTokens: false }; // 模拟余额
  }
}

// 生成交易报告
function generateTradeReport(results) {
  console.log('\n📊 交易报告');
  console.log('='.repeat(50));
  
  const successful = results.filter(r => r.success);
  const failed = results.filter(r => !r.success);
  
  console.log(`✅ 成功交易: ${successful.length}/${results.length} (${((successful.length / results.length) * 100).toFixed(1)}%)`);
  console.log(`❌ 失败交易: ${failed.length}/${results.length} (${((failed.length / results.length) * 100).toFixed(1)}%)`);
  
  if (successful.length > 0) {
    const totalTokens = successful.reduce((sum, r) => sum + r.trade.tokenAmount, 0);
    const totalSol = successful.reduce((sum, r) => sum + r.trade.solAmount, 0);
    const avgPrice = totalSol / totalTokens;
    
    console.log(`\n💎 交易统计:`);
    console.log(`- 总代币购买: ${totalTokens.toLocaleString()} 个`);
    console.log(`- 总SOL支出: ${totalSol.toFixed(3)} SOL`);
    console.log(`- 平均价格: ${avgPrice.toFixed(8)} SOL/代币`);
    
    console.log(`\n🔗 成功交易签名:`);
    successful.forEach((result, index) => {
      console.log(`${index + 1}. ${result.signature}`);
    });
  }
  
  if (failed.length > 0) {
    console.log(`\n❌ 失败交易:`);
    failed.forEach((result, index) => {
      console.log(`${index + 1}. ${result.trade.description} - ${result.error}`);
    });
  }
  
  // 保存报告到文件
  const reportData = {
    timestamp: new Date().toISOString(),
    tokenMint: TOKEN_MINT,
    traderAddress: YOUR_ADDRESS,
    summary: {
      totalTrades: results.length,
      successfulTrades: successful.length,
      failedTrades: failed.length,
      successRate: (successful.length / results.length) * 100,
    },
    trades: results,
  };
  
  const fs = require('fs');
  const reportFile = `trade-report-${Date.now()}.json`;
  fs.writeFileSync(reportFile, JSON.stringify(reportData, null, 2));
  console.log(`\n💾 详细报告已保存到: ${reportFile}`);
}

// 主函数
async function tradeTest() {
  console.log('🚀 代币交易测试');
  console.log('='.repeat(50));
  console.log(`🪙 代币地址: ${TOKEN_MINT}`);
  console.log(`👤 交易地址: ${YOUR_ADDRESS}`);
  console.log(`📡 API地址: ${API_URL}`);
  console.log(`🌐 RPC地址: ${DEVNET_RPC}`);
  
  try {
    // 1. 检查后端服务
    console.log('\n1️⃣ 检查后端服务...');
    await axios.get(`${API_URL}/api/health`);
    console.log('✅ 后端服务正常');
    
    // 2. 检查代币信息
    console.log('\n2️⃣ 获取代币信息...');
    await checkTokenInfo();
    
    // 3. 检查账户余额
    console.log('\n3️⃣ 检查账户余额...');
    await checkAccountBalance();
    
    // 4. 执行模拟交易
    console.log('\n4️⃣ 开始执行交易测试...');
    console.log(`📋 计划执行 ${testTrades.length} 笔交易`);
    
    const results = [];
    
    for (let i = 0; i < testTrades.length; i++) {
      const result = await simulateTradeExecution(testTrades[i], i);
      results.push(result);
      
      // 交易间隔
      if (i < testTrades.length - 1) {
        const delay = Math.random() * 3000 + 2000; // 2-5秒间隔
        console.log(`⏸️ 等待 ${(delay / 1000).toFixed(1)}s 后进行下一笔交易...`);
        await new Promise(resolve => setTimeout(resolve, delay));
      }
    }
    
    // 5. 生成报告
    console.log('\n5️⃣ 生成交易报告...');
    generateTradeReport(results);
    
    console.log('\n🎉 交易测试完成!');
    
  } catch (error) {
    console.log('❌ 测试过程中发生错误:', error.message);
    if (error.response?.data) {
      console.log('错误详情:', JSON.stringify(error.response.data, null, 2));
    }
  }
}

// 添加命令行参数支持
const args = process.argv.slice(2);
if (args.includes('--help') || args.includes('-h')) {
  console.log(`
🎯 代币交易测试脚本使用说明

用法:
  node trade-test.js [选项]

选项:
  --help, -h     显示此帮助信息
  --real         执行真实交易 (需要私钥，谨慎使用!)
  --simulate     仅模拟交易 (默认)

示例:
  node trade-test.js                    # 模拟交易测试
  node trade-test.js --simulate         # 明确指定模拟模式
  node trade-test.js --real             # 真实交易 (危险!)

代币信息:
  - 代币地址: ${TOKEN_MINT}
  - 您的地址: ${YOUR_ADDRESS}

⚠️ 注意:
  - 默认为模拟模式，不会执行真实交易
  - 真实模式需要私钥文件且会消耗真实资金
  - 建议首先使用模拟模式测试
`);
  process.exit(0);
}

// 运行测试
tradeTest();
